//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Resource Application Block
//===============================================================================

using System;
using System.Resources;
using EntLibContrib.Resource.Managers;

namespace EntLibContrib.Resource.Providers
{
  /// <summary>
  /// Base class for resource providers. Contains implementations of common policies
  /// and utilities usable by all resource providers.
  /// </summary>
  public abstract class ResourceProvider : IResourceProvider
  {
		#region Fields
    private string currentResourceManager;
		private ExtendedComponentResourceManager resourceManager;
		private string resourceBaseName;
		#endregion

		#region Properties
		/// <summary>
		/// <para>Gets the current name of the <see cref="EntLibContrib.Resource.ResourceManager"/> using this provider instance.</para>
		/// </summary>
		/// <value>
		/// <para>The name of the <see cref="EntLibContrib.Resource.ResourceManager"/>.</para>
		/// </value>
		public string CurrentResourceManager
		{
			get { return currentResourceManager; }
			set { currentResourceManager = value; }
		}

		/// <summary>
		/// <para>Gets the current <see cref="ExtendedComponentResourceManager" /> instance.</para>
		/// </summary>
		/// <value>
		/// <para>The internal <see cref="ExtendedComponentResourceManager"/> instance.</para>
		/// </value>
		protected ExtendedComponentResourceManager ResourceManager
		{
			get { return resourceManager; }
			set { resourceManager = value; }
		}

		/// <summary>
		/// Gets or sets the name of the resource base.
		/// </summary>
		/// <value>The name of the resource base.</value>
		protected string ResourceBaseName
		{
			get { return resourceBaseName; }
			set { resourceBaseName = value; }
		}
		#endregion

    #region Construction
		/// <summary>
		/// Initializes a new instance of the <see cref="ResourceProvider"/> class.
		/// </summary>
		/// <param name="resourceBaseName">Name of the resource base.</param>
		protected ResourceProvider(string resourceBaseName)
			: this(resourceBaseName, false)
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="ResourceProvider"/> class.
		/// </summary>
		/// <param name="resourceBaseName">Name of the resource base.</param>
		/// <param name="isInternal">if set to <c>true</c> then the provider is for internal resources.</param>
		protected ResourceProvider(string resourceBaseName, bool isInternal)
    {
			// if the provider is for internal resources then validation must be bypassed,
			// otherwise we end up in circles.
			if (!isInternal) 
				ValidateParameter(resourceBaseName);

			this.resourceBaseName = resourceBaseName;
		}
    #endregion

		#region Public Methods
		/// <summary>
		/// Create a Resource Manager to manage the resource for a given resource provider
		/// </summary>
		/// <returns>
		/// A <see cref="ExtendedComponentResourceManager"/> instance
		/// </returns>
		/// <remarks>This method makes a <see cref="ExtendedComponentResourceManager"/> instance publicly available
		/// without the caller needing to know where the resources are provided from</remarks>
		public abstract ExtendedComponentResourceManager CreateResourceManager();
		#endregion

		#region Private Methods
		/// <summary>
		/// Validates the resource base name parameter.
		/// </summary>
		/// <param name="resourceBaseName">Name of the resource base.</param>
		private void ValidateParameter(string resourceBaseName)
		{
			// check for a null base name
			if (string.IsNullOrEmpty(resourceBaseName))
			{
				throw new ArgumentException(InternalResources.ExceptionResourceBaseNameNullOrEmpty);
			}
			// store the base name
			this.resourceBaseName = resourceBaseName;
		}
		#endregion
	}
}